import 'dart:io';
import 'dart:io';
import 'dart:io';
import 'dart:math';

import 'package:android_tool/page/common/app.dart';
import 'package:android_tool/page/common/base_view_model.dart';
import 'package:file_selector/file_selector.dart';
import 'package:flutter/material.dart';
import 'package:flutter_list_view/flutter_list_view.dart';

import 'device_mode.dart';

class BatchManagerViewModel extends BaseViewModel {
  static const int typeFolder = 0;

  TextEditingController segment = TextEditingController();
  TextEditingController port = TextEditingController();
  TextEditingController uninstallPackage = TextEditingController();
  TextEditingController excuCmd = TextEditingController();
  TextEditingController excuAdbCmd = TextEditingController();
  TextEditingController deleteFilePath = TextEditingController();
  var scanSegment = "";
  var scanPort = "";
  var uninstallPackageName = "";
  var deleteFilePathStr = "";
  var excuCmdStr = "";
  var excuAdbStr = "";
  List<DeviceModel> findDevices = [];
  FlutterListViewController scrollController = FlutterListViewController();

  BatchManagerViewModel(BuildContext context) : super(context) {
    App().eventBus.on<AdbPathEvent>().listen((event) {
      adbPath = event.path;
    });
    segment.addListener(() {
      scanSegment = segment.text;
      print("scanSegment:$scanSegment");
    });
    port.addListener(() {
      scanPort = port.text;
      print("scanPort:$scanPort");
    });
    uninstallPackage.addListener(() {
      uninstallPackageName = uninstallPackage.text;
      print("uninstallPackageName:$uninstallPackageName");
    });
    excuAdbCmd.addListener((){
      excuAdbStr = excuAdbCmd.text;
      print("excuAdbCmdStr:$excuAdbStr");
    });
    excuCmd.addListener((){
      excuCmdStr = excuCmd.text;
      print("excuShellCmdStr:$excuCmdStr");
    });
    deleteFilePath.addListener(() {
      deleteFilePathStr = deleteFilePath.text;
      print("deleteFilePathStr:$deleteFilePathStr");
    });
  }

  init() async {
    adbPath = await App().getAdbPath();
    print("adbPath:${adbPath}");
  }

  /**
   * 搜索局域网内设备并自动连接adb
   */
  Future<void> scanAllInLanAndroidDevices() async {
    if (scanSegment.isEmpty) {
      showTipsDialog("请输入网段");
      return;
    }
    if (scanPort.isEmpty) {
      showTipsDialog("请输入端口");
      return;
    }
    setLoading(true, text: "扫描设备");
    findDevices.clear();
    print("adbPath:${adbPath}");
    print("自动扫描 scanSegment:${segment.text} scanPort:${port.text}");
    for (int i = 1; i <= 255; i++) {
      final String ipAddress = '${segment.text}.$i';
      final int devicePort = int.parse(port.text);
      try {
        final Socket socket = await Socket.connect(ipAddress, devicePort,
            timeout: Duration(milliseconds: 100));
        if (socket != null) {
          print('Device at $ipAddress is an Android device.');
          // 这里进一步执行操作，例如连接到设备并执行命令
          var device = DeviceModel(ipAddress, "未连接", "");
          findDevices.add(device);
          socket.destroy();
        }
      } catch (e) {
        // 处理连接超时异常，然后继续扫描下一个设备
        print('Connection to $ipAddress timed out. Moving to the next device.');
      }
    }
    print("扫描结束,发现:${findDevices.length}个设备");
    //尝试adb连接
    connectDevices();
    notifyListeners();
    setLoading(false, text: "");
  }

  /**
   * 查找已经连接了adb的设备
   */
  Future<void> findAllConnectAdbDevices() async {
    setLoading(true, text: "扫描设备");
    findDevices.clear();
    var result = await execAdb(["devices"]);
    print("adb devices 结果:${result?.stdout .toString()}");
    if(result != null && result.stdout !=null){
      List<String> devicesList = result.stdout.toString().split('\n');
      //去掉第一行
      List<String> filteredDevices = devicesList.sublist(1);
      // 打印结果
      for (String find in filteredDevices) {
        if(find.trim().isNotEmpty){
          print("发现设备:${find}");
          String ipAddress = find.split(':')[0].trim();
           var device = DeviceModel(ipAddress, "已连接", "");
           findDevices.add(device);
        }
      }
    }
    print("扫描结束,发现:${findDevices.length}个设备");
    notifyListeners();
    setLoading(false, text: "");
  }

  /**
   * 连接设备
   */
  Future<void> connectDevices() async {
    if (findDevices.isEmpty) {
      showTipsDialog("请输输入设备ip文件清单");
      return;
    }
    if (scanPort.isEmpty) {
      showTipsDialog("请输入端口");
      return;
    }
    var result = await execAdb(['disconnect']);
    for (DeviceModel device in findDevices) {
      print("连接设备:${device.ip}");
      var result = await execAdb(["connect", "${device.ip}:${scanPort}"]);
      print("连接结果:${result?.stdout}");
      if (result!.stdout.contains("connected") ||
          result!.stdout.toString().contains("already")) {
        device.isConnect = "已连接";
      } else {
        device.isConnect = "连接失败";
      }
      device.status = result!.stdout;
    }
    notifyListeners();
  }

  /// 选择文件安装应用
  void install() async {
    final typeGroup = XTypeGroup(label: 'apk', extensions: ['apk']);
    final file = await openFile(acceptedTypeGroups: [typeGroup]);
    for (DeviceModel device in findDevices) {
      if (device.isConnect == "已连接") {
        installApkBatch(device.ip, file?.path ?? "",
            (bool success, String failed) {
          if (success) {
            // 处理安装成功逻辑
            device.status = "安装成功";
          } else {
            // 处理安装失败逻辑
            device.status = "安装失败:${failed}";
          }
        });
      }
    }
  }

  /// 选择文件安装应用
  void selIpFile() async {
    final typeGroup = XTypeGroup(label: 'txt', extensions: ['txt']);
    final file = await openFile(acceptedTypeGroups: [typeGroup]);
    var aa = file?.path ?? "";
    var deviceFile = File(aa);
    String contents = await deviceFile.readAsString();
    print("file content:${contents}");
    List<String> deviceIps = contents.split('\n');
    print("设备数:${deviceIps.length}");
    addDeviceByIpFIle(deviceIps);
  }

  /// 卸载应用
  void uninstallApk() async {
    if (uninstallPackageName.isEmpty) {
      showTipsDialog("请输入卸载应用包名");
      return;
    }
    bool isConfirm = await showTipsDialog("确定批量卸载应用？") ?? false;
    if (!isConfirm) return;
    for (DeviceModel device in findDevices) {
      if (device.isConnect == "已连接") {
        try {
          var result = await execAdb([
            '-s',
            device.ip,
            'uninstall',
            uninstallPackageName,
          ]);
          print("${result?.pid} ${result?.exitCode} ${result?.stdout} ${result?.stderr}");
          if (result != null && result.stdout == "Success") {
            device.status = "卸载成功";
          } else {
            device.status = result?.stdout ?? "卸载失败";
          }
        } catch (e) {
          device.status = e.toString();
        }
      }
    }
    notifyListeners();
  }

  //批量执行指令
  void excuteAdbCmd() async {
    if (excuAdbStr.isEmpty) {
      showTipsDialog("请输入指令");
      return;
    }
    bool isConfirm = await showTipsDialog("确定批量执行adb指令？") ?? false;
    if (!isConfirm) return;
    for (DeviceModel device in findDevices) {
      if (device.isConnect == "已连接") {
        try {
          var result = await execAdb([
            '-s',
            device.ip,
            excuAdbStr,
          ]);
          print("pid=${result?.pid} exitCode=${result?.exitCode} stdout=${result?.stdout} stderr=${result?.stderr}");
          if (result != null && result.exitCode == 0) {
            device.status = "${excuAdbStr}-成功";
          } else {
            device.status = result?.stderr ?? "执行失败";
          }
        } catch (e) {
          device.status = e.toString();
        }
      }
    }
    notifyListeners();
  }

  //批量执行指令
  void excuteShellCmd() async {
    if (excuCmdStr.isEmpty) {
      showTipsDialog("请输入指令");
      return;
    }
    bool isConfirm = await showTipsDialog("确定批量执行shell指令？") ?? false;
    if (!isConfirm) return;
    for (DeviceModel device in findDevices) {
      if (device.isConnect == "已连接") {
        try {
          var result = await execAdb([
            '-s',
            device.ip,
            'shell',
            excuCmdStr,
          ]);
          print("pid=${result?.pid} exitCode=${result?.exitCode} stdout=${result?.stdout} stderr=${result?.stderr}");
          if (result != null && result.exitCode == 0) {
            device.status = "${excuCmdStr}-成功";
          } else {
            device.status = result?.stderr ?? "执行失败";
          }
        } catch (e) {
          device.status = e.toString();
        }
      }
    }
    notifyListeners();
  }

  ///删除文件
  void deleteFile() async {
    if (deleteFilePathStr.isEmpty) {
      showTipsDialog("请输入删除文件绝对路径");
      return;
    }
    bool isConfirm = await showTipsDialog("确定批量删除文件？") ?? false;
    if (!isConfirm) return;
    for (DeviceModel device in findDevices) {
      if (device.isConnect == "已连接") {
        try {
          var result = await execAdb([
            '-s',
            device.ip,
            'shell',
            'rm',
            '-r',
            deleteFilePathStr,
          ]);
          print("${result?.pid} ${result?.exitCode} ${result?.stdout} ${result?.stderr}");
          if (result != null && result.exitCode == 0) {
            device.status = "删除成功";
          } else {
            device.status = result?.stderr ?? "删除失败";
          }
        } catch (e) {
          device.status = e.toString();
        }
      }
    }
    notifyListeners();
  }

  void addDeviceByIpFIle(List<String> deviceIps) {
    findDevices.clear();
    for(String ip in deviceIps){
      var device = DeviceModel(ip.trim(), "未连接", "");
      findDevices.add(device);
    }
    notifyListeners();
  }

  // 重启
  void reboot() async {
    bool isConfirm = await showTipsDialog("确定批量重启？") ?? false;
    if (!isConfirm) return;
    for (DeviceModel device in findDevices) {
      if (device.isConnect == "已连接") {
        try {
          var result = await execAdb([
            '-s',
            device.ip,
            'reboot'
          ]);
          print("${result?.pid} ${result?.exitCode} ${result?.stdout} ${result?.stderr}");
          if (result != null && result.exitCode == 0) {
            device.status = "重启成功";
          } else {
            device.status = result?.stdout ?? "重启失败";
          }
        } catch (e) {
          device.status = e.toString();
        }
      }
    }
    notifyListeners();
  }
}
